Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add setBuffer method for static buffers and/or multiple displays sharing a single buffer #149

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

tttapa
Copy link

@tttapa tttapa commented Oct 15, 2019

This pull request adds a setBuffer method that allows users to supply their own display buffer. This means a static buffer can be used instead of a dynamic one, and that multiple displays can reuse the same buffer.

Motivation

  • I had some code for 2 OLED displays that worked fine on an Arduino UNO with an old version of the library, because it used to share a single display buffer across all display instances.
    However, the new version of the library allocates one buffer for each instance. On an UNO, you need 2 KiB for two displays, so the code I had no longer works.
    By adding the option to let the user decide what buffer to use, this problem is resolved, and you can use multiple OLED displays, even on AVR Arduinos with limited RAM.
  • Static buffers ensure that the compiler has a good estimate of the RAM usage, and the IDE can warn about high memory usage.
  • The static version uses less memory overall. The example with a static buffer uses 84 bytes less program storage, and 1 byte less RAM on an Arduino UNO (tested using the MemoryFree library, AVR Core 1.8.1, hardware SPI). When using multiple dislplays, you can save thousands of bytes of RAM.

Changes

I added two small methods and one member variable to the Adafruit_SSD1306 class. Only setBuffer is public. The actual amound of real code that has been added is just 3 lines and some declarations.

  • void setBuffer(uint8_t *buffer): this methods just sets the pointer to the buffer, and remembers that it shouldn't call free(buffer) later. If a buffer was already allocated, it's deallocated first.
  • void deallocateBuffer(void): this method contains the code that was previously in the destructor. If the pointer to the buffer is not null, and if the buffer was allocated by this object, it's deallocated.
    It is still called from the destructor, and also from the new setBuffer method.
  • enum : bool { Borrowed, Allocated } bufferPolicy: this member variable keeps track of whether the buffer was allocated by this object, or if it's borrowed from someone else.
    It's private, and users of the library don't have to worry about it.

I also added an example, which is just a copy of the ssd1306_128x64_spi example, but with a static buffer instead of a dynamic one.

Finally, I provided a macro to detect whether the setBuffer method is available. This can be useful when different version of the library remain in use (e.g. Teensyduino comes with its own version).

Known Limitations

None.
These changes should be 100% backwards compatible. If you don't use the new setBuffer method, nothing changes.

Tests

I tested the new and the old example for an SPI 128×64 SSD1306 display on an Arduino UNO and a Teensy 3.2.
Everything worked as expected.

By setting it before calling the begin method, you can
avoid dynamic memory usage, and you can share one
buffer between multiple displays.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant